﻿namespace Mp3Observer.Common.Behaviors
{
    #region usings
    
    using System;
    using System.Windows;
    using System.Windows.Interactivity;

    #endregion

    /// <summary>
    /// This interaction trigger can be used to listen on a RoutedEvent and to execute a command.
    /// </summary>
    /// <example>
    /// <code>
    /// <![CDATA[ 
    /// <ListBox ItemsSource="{Binding Path=...}" ...>
    ///     <i:Interaction.Triggers>
    ///         <behaviours:RoutedEventTrigger RoutedEvent="KeyDown">
    ///             <behaviours:CommandAction Command="{Binding DoubleClickCommand}" />
    ///         </behaviours:RoutedEventTrigger>
    ///         <behaviours:RoutedEventTrigger RoutedEvent="PreviewMouseLeftButtonDown">
    ///             <behaviours:CommandAction Command="{Binding DoubleClickCommand}" />
    ///         </behaviours:RoutedEventTrigger>
    ///     </i:Interaction.Triggers>
    /// ]]>
    /// </code>
    /// </example>
    public class RoutedEventTrigger : EventTriggerBase<DependencyObject>
    {
        /// <summary>
        /// the routed event we use.
        /// </summary>
        private RoutedEvent routedEvent;

        /// <summary>
        /// Initializes a new instance of the <see cref="RoutedEventTrigger"/> class.
        /// </summary>
        public RoutedEventTrigger()
        {
        }

        /// <summary>
        /// Gets or sets the routed event.
        /// </summary>
        /// <value>The routed event.</value>
        public RoutedEvent RoutedEvent
        {
            get { return this.routedEvent; }
            set { this.routedEvent = value; }
        }

        /// <summary>
        /// Called after the trigger is attached to an AssociatedObject.
        /// </summary>
        protected override void OnAttached()
        {
            var behavior = this.AssociatedObject as Behavior;
            var associatedElement = this.AssociatedObject as FrameworkElement;
            if (behavior != null)
                associatedElement = ((IAttachedObject)behavior).AssociatedObject as FrameworkElement;
            if (associatedElement == null)
                throw new ArgumentException("Routed Event trigger can only be associated to framework elements");
            if (this.RoutedEvent != null)
                associatedElement.AddHandler(RoutedEvent, new RoutedEventHandler(this.OnRoutedEvent));
        }

        /// <summary>
        /// Specifies the name of the Event this EventTriggerBase is listening for.
        /// </summary>
        /// <returns>the name of the routed event as string</returns>
        protected override string GetEventName()
        {
            return RoutedEvent.Name;
        }

        /// <summary>
        /// Called when [routed event].
        /// </summary>
        /// <param name="sender">The sender.</param>
        /// <param name="args">The <see cref="System.Windows.RoutedEventArgs"/> instance containing the event data.</param>
        private void OnRoutedEvent(object sender, RoutedEventArgs args)
        {
            this.OnEvent(args);
        }
    }
}
